define osc (4)
tiempo var word
mseg var word
memo var byte
b0 var memo.0
b1 var memo.1
b2 var memo.2
b3 var memo.3
b4 var memo.4
incodigo var byte
b7 var incodigo.0
codigo var byte
contador var byte
cont var byte
minuto var byte
tem1 var byte 
tem2 var byte  
tem3 var byte
display var byte [10]
digitos var byte [5]
clear
intcon = %00000000
ON INTERRUPT GOTO relog
trisa=16
trisb=0
porta=0
portb=0
'
' defino los digitos
'
display 
display [0]=%11111100  ' 0
display [1]=%00001100  ' 1
display [2]=%11011010  ' 2
display [3]=%10011110  ' 3
display [4]=%00101110  ' 4
display [5]=%10110110  ' 5
display [6]=%11110110  ' 6
display [7]=%00011100  ' 7
display [8]=%11111110  ' 8
display [9]=%00111110  ' 9
display [10]=%00000000 ' apagado 
'
'      4      
'    ++++     
' 5 +    + 3  
'   +  1 +   
'    ++++    
' 6 +    + 2  
'   +    +   
'    ++++    
'      7      
'
iniciar:
option_reg = %10000111
low porta.0
tiempo=9000
memo=0
'
' establece el tiempo cuenta atras y activacion
'
programa:
gosub descomponer
gosub mostrar
high porta.2 ' suvimos y bajamos el tiempo a.2, a.3 empieza la cuenta atras
if porta.2=0 and b1=0 and tiempo>3000 then tiempo=tiempo-3000:b1=1
if porta.2=1 then b1=0
codigo=codigo+1 ' variable que nos dara el codigo para desblokear
if codigo=32 then codigo=0 ' sin complicaciones un numero del 0 al 31 en binario
low porta.2: low porta.3
if porta.2=1 and b2=0 and tiempo<54000 then tiempo=tiempo+3000:b2=1
if porta.2=0 then b2=0
if porta.3=0 then goto programa
'
' activacion cuenta atras
'
incodigo=codigo
gosub descomponercod ' descomponemos el codigo en binario 
incodigo=0            ' para mostrarlo en pantalla
for tem3=0 to 30 
    low porta.3 ' un reten nos obliga a tener pulsado 2 segundos para empezar
    gosub mostrar
    if porta.3=0 then programa 
next tem3
pause 250
while porta.3=1 ' en cuanto sueltes empieza la cuenta atras
    GOSUB mostrar
    low porta.3
wend
intcon = %10100000
tmr0=60
'
' entra en la cuenta atras
'
cuentatras:
while porta.0=0 ' siempre que se alla activado la sirena sale
    if b3=1 then gosub descomponer ' descomponemos el tiempo al reducirse
    gosub mostrar
    if porta.4=0 then high porta.0 ' fallo pulso y activacion
    low porta.2
    if porta.2=1 then introcucir_cod ' introducir codigo
    high porta.2:high porta.3
    if porta.2=0 then introcucir_cod ' introducir codigo
    if porta.3=0 and b0=0 then ' muestra codigo una vez 0,5seg*
        incodigo=codigo
        gosub descomponercod
        incodigo=0
        b0=1
        for tem3=0 to 22
            gosub mostrar
            pauseus 50
        next tem3  
    endif
wend
'
' a.0 se a activado
'
intcon=0
gosub descomponer  
for tem1=0 to 250 ' se mantiene aqui 2 minutos
    for tem2=0 to 200
        gosub mostrar
        pauseus 200
    next tem2
next tem1
goto iniciar ' y vuelve a iniciarse
'
' canvia la pantalla para introducir el codigo
'
introcucir_cod:
contador=40
b7=porta.2
b1=1
b2=1
repeat  ' se mantiene un tiempo en la pantalla desactivacion
    high porta.2
    if porta.2=0 and b2=0 then  'incrementa bit 0
        b2=1
        incodigo=incodigo<<1
        b7=0
        contador=40
    endif
    if porta.2=1 then b2=0              
    low porta.2:low porta.3
    if porta.2=1 and b1=0 then ' incrementa bit1
        b1=1
        incodigo=incodigo<<1
        b7=1
        contador=40
    endif
    if porta.2=0 then b1=0
    gosub descomponercod
    gosub mostrar
    if porta.3=1 then ' comprueva que el codigo de la pantalla sea el mismo
        incodigo=incodigo<<3
        incodigo=incodigo>>3         
        if incodigo=codigo then ' si es el mismo va al principio
            intcon = %00000000
            pause 2000
            goto iniciar
        endif
        option_reg= option_reg-2 ' si no es corecto aumenta el ritmo tmr0
        contador=1
    endif    
    if option_reg=129 then ' al tercer fallo se activa a.0
        high porta.0
        intcon=0
        incodigo=0
        contador=1
    endif    
    contador=contador-1
until contador=0
incodigo=0        
goto cuentatras
'
' descomponer los caracteres minutos y milisegundos
'
descomponer:
minuto=TIEMPO/600
MSEG=TIEMPO-(minuto*600)
digitos[0]=mseg//10
mseg=mseg/10
digitos[1]=mseg//10
digitos[2]=mseg/10
digitos[3]=minuto//10
digitos[4]=minuto/10
digitos[5]=%00000110
return
'
' descomponer el codigo aleatorio
'
descomponercod:
tem3=incodigo
for tem1=0 to 4
    digitos[tem1]=b7
    incodigo=incodigo>>1
next tem1
digitos[5]=%00001000
incodigo=tem3
return
'
' mostrar caracteres en la pantalla display
'
mostrar:
for tem1=0 to 50 ' barridos
    for tem2=0 to 5 ' de los 5 display's y 3 led
        pauseus 5
        high porta.1 
        portb=display[digitos[tem2]]
        pauseus 120
        portb=display[10]
        low porta.1
    next tem2
next tem1
return
'
' interruccion timer decenas milisegundos
'
DISABLE
relog:
tmr0=60 ' el tmr0 mas o menos ajustado a una centesima de segundo
cont=cont+1
if cont=2 then 
    cont=0
    tiempo=tiempo-1
    b3=1
endif
if tiempo=0 then ' se acavo el tiempo activa a.0 y desavilita las interruciones
    high porta.0
    intcon = %00000000
endif
intcon.2=0
RESUME
ENABLE